﻿using System;
using System.IO;
using ITSP.SharePoint.CacheRefresh.Interfaces;
using ITSP.SharePoint.CacheRefresh.Repositories;
using ITSP.SharePoint.CacheRefresh.SpecialCases;
using Microsoft.Practices.SharePoint.Common.Logging;
using Microsoft.Practices.SharePoint.Common.ServiceLocation;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

namespace ITSP.SharePoint.CacheRefresh
{
    /// <summary>
    /// SharePoint Cache File Dependency that uses the SharePoint Lists as configuration.
    /// </summary>
    /// <createdby>Simon Doy</createdby>
    public class SPCacheFileDependency : System.Web.Caching.CacheDependency
    {
        #region Properties

        /// <summary>
        /// Does the Cache File Dependency exist?
        /// </summary>
        public bool Exists { get; protected set; }

        /// <summary>
        /// Is the Cache Dependency Enabled?
        /// </summary>
        public bool Enabled { get; protected set; }

        /// <summary>
        /// How long does the cache entry last for?
        /// </summary>
        public int CacheLifeTime { get; protected set; }

        #endregion

        #region Constructors

        /// <summary>
        /// Default Constructor
        /// </summary>
        public SPCacheFileDependency()
        :base()
        {
            
        }

        /// <summary>
        /// Constructor which takes in a Cache Configuration Item
        /// </summary>
        /// <param name="item">The Cache Configuration Item which configures the SPCacheFileDependency object.</param>
        public SPCacheFileDependency(ICacheConfigItem item)
            :base(item.CacheDependencyPath)
        {
            Exists = true;
            Enabled = item.CacheEnabled;
            CacheLifeTime = item.CacheFrequency;
        }

        /// <summary>
        /// Constructor which takes a Cache Configuration Item and a Date/Time to start caching the objects from.
        /// </summary>
        /// <param name="item">The Cache Configuration Item which configures the SPCacheFileDependency object.</param>
        /// <param name="startDateTime">The Date/Time to start the Cache Dependency working from.</param>
        public SPCacheFileDependency(ICacheConfigItem item, DateTime startDateTime)
            : base(item.CacheDependencyPath, startDateTime)
        {
            Exists = true;
            Enabled = item.CacheEnabled;
            CacheLifeTime = item.CacheFrequency;
        }

        #endregion

        /// <summary>
        /// Resolve the Cache File Path using the SharePoint Site and the Cache Key for the entry in the list.
        /// </summary>
        /// <param name="cacheWebHostUrl">The Web Application Url that hosts the Cache Configuration List</param>
        /// <param name="cacheKey">The Key to get the File Path for</param>
        /// <returns>A Cache Configuration Item based on the key.</returns>
        public static ICacheConfigItem ResolveCacheFilePath(string cacheWebHostUrl, string cacheKey)
        {
            ICacheConfigItem configItem = new SPCacheConfigItemNotFound();

            try
            {
                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    SPCacheConfigurationRepository repository=new SPCacheConfigurationRepository(cacheWebHostUrl);
                    ICacheConfigItem cacheItem = repository.Get(cacheKey);
                    if (cacheItem.Exists)
                    {
                        configItem = cacheItem;
                        if (!System.IO.File.Exists(configItem.CacheDependencyPath))
                        {
                            throw new FileNotFoundException("Unable to setup Cache Dependency, Cache File Not Found",
                                                            configItem.CacheDependencyPath);
                        }
                    }
                });

                if(String.IsNullOrEmpty(configItem.CacheDependencyPath))
                {
                    throw new ApplicationException(String.Format("Unable to find the Cache Configuration Key {0} in {1}", cacheKey, cacheWebHostUrl));
                }
            }
            catch (System.IO.FileNotFoundException fileex )
            {
                ILogger logger = SharePointServiceLocator.GetCurrent().GetInstance<ILogger>();
                logger.TraceToDeveloper(fileex,0,TraceSeverity.High, Common.Constants.Logging.DefaultLoggingCategory);
                
                //reset the item
                configItem=new SPCacheConfigItemNotFound();
            }
            

            return configItem;
        }

    }
}
